
#define WINNT 0x0500
#include "Win32Events.h"
#include "Common/Errors.h"

using namespace ttg::threads::win32;

//----------------------
//--- Win32FastEvent ---
//----------------------

Win32FastEvent::Win32FastEvent()
{
	this->flag = 0;
}

void Win32FastEvent::wait()
{
	while (!InterlockedExchange(&flag, 0))
		Sleep(0);
}

void Win32FastEvent::wait(double time)
{
	DWORD t_start = GetTickCount();
	DWORD t_wait = (DWORD)(time * 1000);
	while (!InterlockedExchange(&flag, 0) &&
		   (GetTickCount() - t_start) < t_wait)
		Sleep(0);
}

void Win32FastEvent::rise()
{
	InterlockedExchange(&flag, 1);
}

//----------------------
//--- Win32SlowEvent ---
//----------------------

Win32SlowEvent::Win32SlowEvent()
{
	if ((ev = CreateEventA(NULL, FALSE, FALSE, NULL)) == NULL)
		throw Error(Error::FATAL, "SlowEvent", "SlowEvent",
					"Cannot create WinAPI event");
}

void Win32SlowEvent::wait()
{
	if (WaitForSingleObject(ev, INFINITE) == WAIT_FAILED)
		throw Error(Error::FATAL, "SlowEvent", "wait", "Cannot sleep");
}

void Win32SlowEvent::wait(double time)
{
	if (WaitForSingleObject(ev, (DWORD)(time * 1000)) == WAIT_FAILED)
		throw Error(Error::FATAL, "SlowEvent", "wait", "Cannot sleep");
}

void Win32SlowEvent::rise()
{
	if (!SetEvent(ev))
	{
		//DWORD err = GetLastError();
		throw Error(Error::FATAL, "SlowEvent", "rise", "Cannot set event", GetLastError());
	}
}

Win32SlowEvent::~Win32SlowEvent()
{
	CloseHandle(ev);
}
